package com.example.myapp.utils;

import com.example.myapp.models.Direction;
import com.example.myapp.models.Game;

import java.util.ArrayList;
import java.util.List;

public class StateAnalysis {
    public static int calculateEmptySlots(Game game) {
        int count = 0;
        for (int i = 0; i < Game.MATRIX_WIDTH; i++) {
            for (int j = 0; j < Game.MATRIX_WIDTH; j++) {
                if (game.getStateMatrix()[i * Game.MATRIX_WIDTH + j] == -1) {
                    count ++;
                }
            }
        }
        return count;
    }

    public static int getCountByFaction(Game game, int faction) {
        int count = 0;
        for (int i = 0; i < Game.MATRIX_WIDTH; i++) {
            for (int j = 0; j < Game.MATRIX_WIDTH; j++) {
                if (game.getStateMatrix()[i * Game.MATRIX_WIDTH + j] == faction) {
                    count ++;
                }
            }
        }
        return count;
    }

    public static List<int[]> listCapablePoints(Game game, int part) {
        List<int[]> capable = new ArrayList<>();

        for (int i = 0; i < Game.MATRIX_WIDTH; i++) {
            for (int j = 0; j < Game.MATRIX_WIDTH; j++) {
                if (game.getStateMatrix()[i * Game.MATRIX_WIDTH + j] == -1 && testFlip(game, part, i, j)) {
                    capable.add(new int[]{i, j});
                }
            }
        }

        return capable;
    }

    public static boolean testFlip(Game game, int part, int x, int y) {
        return listAllFlippable(game, part, x, y).size() != 0;
    }

    public static List<int[]> listAllFlippable(Game game, int part, int x, int y) {
        List<int[]> result = new ArrayList<>();
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.TOPLEFT));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.TOPRIGHT));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.DOWNLEFT));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.DOWNRIGHT));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.UP));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.DOWN));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.LEFT));
        result.addAll(listDirectionalFlippable(game, part, x, y, Direction.RIGHT));
        return result;
    }

    public static List<int[]> listDirectionalFlippable(Game game, int part, int x, int y, Direction d) {
        List<int[]> result = new ArrayList<>();
        int state;
        do {
            state = getNextState(game, x, y, d);

            if (state == -1) {
                result.clear();
                return result;
            } else if (state == part) {
                return result;
            }

            x += d.getDx();
            y += d.getDy();

            result.add(new int[]{x, y});
        } while(true);
    }

    private static int getNextState(Game game, int x, int y, Direction d) {
        if (x < 0 || y < 0 || x >= Game.MATRIX_WIDTH || y >= Game.MATRIX_WIDTH) {
            return -1;
        }

        x += d.getDx();
        y += d.getDy();

        if (x < 0 || y < 0 || x >= Game.MATRIX_WIDTH || y >= Game.MATRIX_WIDTH) {
            return -1;
        }

        return game.getStateMatrix()[x * Game.MATRIX_WIDTH + y];
    }
}
